package com.cn.JUC.utils.case2;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Title Lock与Condition实现阻塞队列
 * @Description 当notFull等待时，不能访问enq方法；当notEmpty等待时，不能访问deq方法
 * @Author CAI ZHAI
 * @Date 2021/9/1 17:27
 **/
public class BlockedQueueImpl<T>{
    final Lock lock = new ReentrantLock();
    // 条件变量：队列不满
    final Condition notFull = lock.newCondition();
    // 条件变量：队列不空
    final Condition notEmpty = lock.newCondition();
    
    //队列：假设最多放16个元素
    List<String> list = new ArrayList<>(16);
    
    // 入队
    void enq(T x){
        lock.lock();
        try{
            while(list.size()==16){ //队列已满
                // 等待队列不满
                try{
                    notFull.await();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            // 省略入队操作...
            //入队后,通知可出队
            notEmpty.signal();
        }finally{
            lock.unlock();
        }
    }
    
    // 出队
    void deq(){
        lock.lock();
        try{
            while(list.size()==0){ //队列已空
                // 等待队列不空
                try{
                    notEmpty.await();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            // 省略出队操作...
            //出队后，通知可入队
            notFull.signal();
        }finally{
            lock.unlock();
        }
    }
}